package com.niiwoo.civet.account.service.local.bill;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.niiwoo.civet.account.dao.entity.*;
import com.niiwoo.civet.account.dao.mapper.BankTypeMapper;
import com.niiwoo.civet.account.dto.bill.BillBase;
import com.niiwoo.civet.account.dto.request.SaveAccountBillRequest;
import com.niiwoo.civet.account.dto.request.SaveBillDetailRequest;
import com.niiwoo.civet.account.dto.response.CheckAccountBillDTO;
import com.niiwoo.civet.account.enums.*;
import com.niiwoo.civet.account.service.local.AccountService;
import com.niiwoo.civet.account.service.local.BankCardService;
import com.niiwoo.civet.base.enums.ChannelCodeEnum;
import com.niiwoo.civet.trade.dto.response.myloan.ProjectDetailResponseDTO;
import com.niiwoo.civet.trade.service.myloan.MyLoanDubboService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 账单处理Facade
 *
 * @author xiaoyingping
 * @create 2017-11-22 10:42
 **/
@Service
@Slf4j
public class NiiwooBillFacade {

    @Autowired
    private NiiwooBillService niiwooBillService;
    @Autowired
    private AccountService accountService;
    @Autowired
    private NiiwooBillPlateformService niiwooBillPlateformService;
    @Autowired
    private NiiwooBillGuaranteeService niiwooBillGuaranteeService;
    @Autowired
    private BillBaseService billBaseService;
    @Autowired
    private BankCardService bankCardService;
    @Autowired
    private BankTypeMapper bankTypeMapper;

    @Reference(version = "1.0.0")
    private MyLoanDubboService myLoanDubboService;


    /**
     * 批量新增账户账单和账单明细
     *
     * @param accountBillRequestList
     */
    @Transactional
    public void saveAccountBillList(List<SaveAccountBillRequest> accountBillRequestList) {
        log.info("saveAccountBillList start:{}", JSON.toJSONString(accountBillRequestList));
        for (SaveAccountBillRequest saveAccountBillRequest : accountBillRequestList) {
            this.saveAccountBillCommon(saveAccountBillRequest, true);
        }
    }


    private Long saveAccountBillCommon(SaveAccountBillRequest accountBillRequest, boolean isSaveBillDetail) {
        //校验参数
        verifyParam(accountBillRequest, isSaveBillDetail);

        //新增AccountBillBase
        BillStatusEnum statusEnum = accountBillRequest.getStatus();
        if (Objects.isNull(statusEnum)) {
            statusEnum = BillStatusEnum.SUCCESS;
        }

        ChannelCodeEnum channelCodeEnum = accountBillRequest.getChannelCode();
        if (Objects.isNull(channelCodeEnum)) {
            channelCodeEnum = ChannelCodeEnum.APP;
        }

        BillBase accountBillBase = new BillBase();
        AccountBase accountBase = null;
        boolean isThirdBill;
        if(accountBillRequest.getAccountId() >= 0){
            //存管账单
            isThirdBill = false;
            accountBase = accountService.loadAccountById(accountBillRequest.getAccountId());
            accountBillBase.setUserId(accountBase.getUserId());
            accountBillBase.setOrgId(accountBase.getOrgId());
        }else{
            //Third账单
            isThirdBill = true;
            accountBillBase.setUserId(accountBillRequest.getUserId());
            accountBillBase.setOrgId("");
        }
        accountBillBase.setBillType(accountBillRequest.getBillType().getCode());
        accountBillBase.setRequestNo(accountBillRequest.getRequestNo());
        accountBillBase.setAccountId(accountBillRequest.getAccountId());
        accountBillBase.setAmount(accountBillRequest.getAmount());
        accountBillBase.setInoutType(accountBillRequest.getInoutType().getType());
        accountBillBase.setBalanceAmount(accountBillRequest.getBalanceAmount());
        accountBillBase.setOrderId(String.valueOf(accountBillRequest.getOrderId()));
        if (Objects.nonNull(accountBillRequest.getOrderType())){
            accountBillBase.setOrderType(accountBillRequest.getOrderType().getCode());
        }
        accountBillBase.setStatus(statusEnum.getValue());
        accountBillBase.setProjectId(accountBillRequest.getProjectId());
        accountBillBase.setInvestId(accountBillRequest.getInvestId());
        accountBillBase.setGuaranteeId(accountBillRequest.getGuaranteeId());
        billBaseService.addBillBase(accountBillBase);

        //新增BillDetail
        if (isSaveBillDetail) {
            List<SaveBillDetailRequest> billDetailList = accountBillRequest.getSaveBillDetailList();
            if (!CollectionUtils.isEmpty(billDetailList)) {
                this.addAccountBillDetailList(accountBase, accountBillBase, billDetailList, channelCodeEnum, isThirdBill);
            }
        }

        return accountBillBase.getId();
    }

    private void addAccountBillDetailList(AccountBase accountBase, BillBase billBase, List<SaveBillDetailRequest> billDetailList, ChannelCodeEnum channelCodeEnum, boolean isThirdBill) {
        //获取项目相关属性
        Integer totalPeriods = null;
        String projectTitle = "";
        Byte projectType = null;
        if (Objects.nonNull(billBase.getProjectId())) {
            ProjectDetailResponseDTO projectDetailResponseDTO = myLoanDubboService.queryProjectDetailByProjectId(billBase.getProjectId());
            log.info("projectId={},addAccountBillDetailList-rpc查询订单projectDetailResponseDTO={}",billBase.getProjectId(),JSON.toJSONString(projectDetailResponseDTO));
            Assert.notNull(projectDetailResponseDTO, "查询不到项目:{}" + billBase.getProjectId());
            projectTitle = projectDetailResponseDTO.getTitle();
            totalPeriods = projectDetailResponseDTO.getDeadline();
            projectType = projectDetailResponseDTO.getType();
        }

        for (SaveBillDetailRequest billDetail : billDetailList) {
            //初始化属性
            String bankAccountNo = "";
            String bankCode = "";
            String bankName = "";
            BillSecondSubjectEnum secondSubjectEnum = billDetail.getBillSecondSubjectEnum();

            //判断是否获取银行卡信息
            boolean bankContain = BillSecondSubjectEnum.listBankImagEnum().contains(secondSubjectEnum.getCode());
            if (bankContain) {
                BankCard bankCard;
                if (isThirdBill) {
                    bankCard = bankCardService.getSimpleUserBankCard(billBase.getUserId());
                } else {
                    bankCard = bankCardService.loadBankCard(accountBase);
                }
                BankType bankType = bankTypeMapper.selectByPrimaryKey(bankCard.getBankTypeId());
                Assert.notNull(bankType, "根据bankTypeID未查询到对应的类型数据 ");

                bankAccountNo = bankCard.getBankAccountNo();
                bankCode = bankCard.getBankCode();
                bankName = bankType.getBankName();
            }

            //按userType保存到对应的表中
            BillUserTypeEnum userType = secondSubjectEnum.getFirstSubject().getUserType();
            Assert.notNull(userType, "二级科目中用户类型不能为空");
            if (BillUserTypeEnum.GENERAL == userType) {
                //普通用户和合作机构
                NiiwooBill niiwooBill = new NiiwooBill();
                niiwooBill.setAmount(billDetail.getAmount());
                niiwooBill.setSecondSortCode(secondSubjectEnum.getCode());
                niiwooBill.setBankAccountNo(bankAccountNo);
                niiwooBill.setBankCode(bankCode);
                niiwooBill.setBankName(bankName);
                niiwooBill.setProjectType(projectType);
                niiwooBill.setProjectTitle(projectTitle);
                niiwooBill.setTotalPeriods(totalPeriods);
                niiwooBill.setCurrentPeriod(billDetail.getCurrentPeriod());
                niiwooBill.setRelationUserId(billDetail.getRelationUserId());
                niiwooBill.setRelationAccountId(billDetail.getRelationAccountId());
                niiwooBill.setChannelCode(channelCodeEnum.getChanelCode());
                niiwooBill.setBackTime(billDetail.getBackTime());
                if (billDetail.getBillRemark3Enum() != null || StringUtils.isNotBlank(billDetail.getRemark2())) {
                    String remark2 = billDetail.getBillRemark3Enum() == null ? billDetail.getRemark2() : billDetail.getBillRemark3Enum().getDesc();
                    niiwooBill.setRemark2(remark2);
                }
                if(Objects.nonNull(accountBase)){
                    niiwooBill.setIsVisible(accountBase.getIsShowBill());
                }


                niiwooBillService.addNiiwooBill(billBase, niiwooBill);
            } else if (BillUserTypeEnum.GUARANTEE_AGENCY == userType || BillUserTypeEnum.COOPERATE_AGENCY == userType) {
                //担保机构
                NiiwooBillGuarantee niiwooBillGuarantee = new NiiwooBillGuarantee();
                niiwooBillGuarantee.setAmount(billDetail.getAmount());
                niiwooBillGuarantee.setSecondSortCode(secondSubjectEnum.getCode());
                niiwooBillGuarantee.setBankCode(bankCode);
                niiwooBillGuarantee.setProjectType(projectType);
                niiwooBillGuarantee.setRelationUserId(billDetail.getRelationUserId());
                niiwooBillGuarantee.setRelationAccountId(billDetail.getRelationAccountId());
                niiwooBillGuarantee.setChannelCode(channelCodeEnum.getChanelCode());
                niiwooBillGuaranteeService.addNiiwooBillGuarantee(billBase, niiwooBillGuarantee);
            } else if (BillUserTypeEnum.PLATFORM == userType) {
                //平台
                NiiwooBillPlatform niiwooBillPlatform = new NiiwooBillPlatform();
                niiwooBillPlatform.setAmount(billDetail.getAmount());
                niiwooBillPlatform.setSecondSortCode(secondSubjectEnum.getCode());
                niiwooBillPlatform.setCurrentPeriod(billDetail.getCurrentPeriod());
                niiwooBillPlatform.setProjectType(projectType);
                niiwooBillPlatform.setRelationUserId(billDetail.getRelationUserId());
                niiwooBillPlatform.setRelationAccountId(billDetail.getRelationAccountId());
                niiwooBillPlatform.setChannelCode(channelCodeEnum.getChanelCode());
                niiwooBillPlateformService.addNiiwooBillPlatform(billBase, niiwooBillPlatform);
            }
        }
    }

    //验证参数传的是否正确
    private void verifyParam(SaveAccountBillRequest accountBillRequest, boolean isSaveBillDetail) {
        Assert.notNull(accountBillRequest, "accountBillRequest不能为空");
        Assert.notNull(accountBillRequest.getUserId(), "userId不能为空");
        Assert.notNull(accountBillRequest.getBillType(), "billType不能为空");
        Assert.notNull(accountBillRequest.getAccountId(), "accountId不能为空");
        Assert.hasLength(accountBillRequest.getRequestNo(), "requestNo不能为空");
        Assert.notNull(accountBillRequest.getAmount(), "amount不能为空");
        Assert.notNull(accountBillRequest.getInoutType(), "inoutType不能为空");
        Assert.notNull(accountBillRequest.getBalanceAmount(), "balanceAmount不能为空");
        if(Objects.isNull(accountBillRequest.getChannelCode()) || accountBillRequest.getChannelCode() == ChannelCodeEnum.APP){
            Assert.notNull(accountBillRequest.getOrderId(), "orderId不能为空");
            Assert.notNull(accountBillRequest.getOrderType(), "orderType不能为空");
        }

        if (isSaveBillDetail) {
            List<SaveBillDetailRequest> saveBillDetailRequestList = accountBillRequest.getSaveBillDetailList();
            if (!CollectionUtils.isEmpty(saveBillDetailRequestList)) {
                saveBillDetailRequestList.forEach(billDetail -> {
                    Assert.notNull(billDetail, "账单对象不能为空");
                    Assert.notNull(billDetail.getAmount(), "金额不能为空");
                    Assert.notNull(billDetail.getBillSecondSubjectEnum(), "二级科目枚举不能为空");
                    if (Objects.nonNull(accountBillRequest.getProjectId())) {
                        BillFirstSubjectEnum firstEnum = billDetail.getBillSecondSubjectEnum().getFirstSubject();
                        List<String> currentPeriodList = BillSecondSubjectEnum.listCurrentPeriodEnum();
                        boolean containPeriod = currentPeriodList.contains(firstEnum.getCode());
                        if (containPeriod) {
                            Assert.notNull(billDetail.getCurrentPeriod(), "还款或者收款当期期数不能为空");
                        }
                    }
                });
            }
        }

    }



    /***
     * 获取账单明细列表
     * @param accountBillBase
     * @return
     */
    public List<CheckAccountBillDTO> getCheckAccountBills(BillBase accountBillBase){
        BillUserTypeEnum billUserTypeEnum = BillUserTypeEnum.getEnumByCode(accountBillBase.getBillType());
        List<CheckAccountBillDTO> checkAccountBillDTOList = new ArrayList<>();
        switch (billUserTypeEnum){
            case GENERAL:{//普通用户
                List<NiiwooBill> billList = niiwooBillService.getCheckAccountBillsByBaseId(accountBillBase.getUserId(), accountBillBase.getId());
                for(NiiwooBill niiwooBill : billList){
                    CheckAccountBillDTO checkAccountBillDTO = new CheckAccountBillDTO();
                    checkAccountBillDTO.setFirstSortCode(niiwooBill.getFirstSortCode());
                    checkAccountBillDTO.setSecondSortCode(niiwooBill.getSecondSortCode());
                    checkAccountBillDTO.setInOutType(niiwooBill.getInoutType());
                    checkAccountBillDTO.setTime(niiwooBill.getCreateTime());
                    checkAccountBillDTO.setAmount(niiwooBill.getAmount());
                    checkAccountBillDTOList.add(checkAccountBillDTO);
                }
            }break;
            case GUARANTEE_AGENCY : case  COOPERATE_AGENCY:{//担保机构|合作机构
                List<NiiwooBillGuarantee> niiwooBillGuaranteeList = niiwooBillGuaranteeService.getCheckAccountBillsByBaseId(accountBillBase.getId(), accountBillBase.getCreateTime());
                for(NiiwooBillGuarantee niiwooBillGuarantee : niiwooBillGuaranteeList){
                    CheckAccountBillDTO checkAccountBillDTO = new CheckAccountBillDTO();
                    checkAccountBillDTO.setFirstSortCode(niiwooBillGuarantee.getFirstSortCode());
                    checkAccountBillDTO.setSecondSortCode(niiwooBillGuarantee.getSecondSortCode());
                    checkAccountBillDTO.setInOutType(niiwooBillGuarantee.getInoutType());
                    checkAccountBillDTO.setTime(niiwooBillGuarantee.getCreateTime());
                    checkAccountBillDTO.setAmount(niiwooBillGuarantee.getAmount());
                    checkAccountBillDTOList.add(checkAccountBillDTO);
                }
            }break;
            case PLATFORM:{//平台
                List<NiiwooBillPlatform> niiwooBillPlatformList = niiwooBillPlateformService.getCheckAccountBillsByBaseId(accountBillBase.getId(), accountBillBase.getCreateTime());
                for(NiiwooBillPlatform niiwooBillPlatform : niiwooBillPlatformList){
                    CheckAccountBillDTO checkAccountBillDTO = new CheckAccountBillDTO();
                    checkAccountBillDTO.setFirstSortCode(niiwooBillPlatform.getFirstSortCode());
                    checkAccountBillDTO.setSecondSortCode(niiwooBillPlatform.getSecondSortCode());
                    checkAccountBillDTO.setInOutType(niiwooBillPlatform.getInoutType());
                    checkAccountBillDTO.setTime(niiwooBillPlatform.getCreateTime());
                    checkAccountBillDTO.setAmount(niiwooBillPlatform.getAmount());
                    checkAccountBillDTOList.add(checkAccountBillDTO);
                }
            }break;
        }
        return checkAccountBillDTOList;
    }


}
